using System;
using System.Collections.Generic;

namespace MLSharp.RProject.Amore
{
	/// <summary>
	/// A neural network created via the AMORE package.  See <see cref="AmoreNeuralNetworkFactory"/>.
	/// </summary>
	public class AmoreNeuralNetwork : RNeuralNetworkBase
	{
		#region Const Fields

		/// <summary>
		/// The name of the NN library to use.
		/// </summary>
		private const string mLibraryName = "AMORE";

		/// <summary>
		/// The command to run the network.
		/// </summary>
		private const string mRunCommand = "sim(result$net, x)";

		#endregion

		#region Public Constructors

		/// <summary>
		/// Creates a network.
		/// </summary>
		/// <param name="workingDirectory">The working directory to use.</param>
		/// <param name="rPath">The path to R.exe.</param>
		/// <param name="networkContents">The network.</param>
		public AmoreNeuralNetwork(string workingDirectory, string rPath, string networkContents) 
			: base(workingDirectory, rPath, networkContents, mLibraryName, mRunCommand)
		{
		}

		#endregion

		#region Protected Methods

		/// <summary>
		/// Verifies that the output is in the correct, expected format and
		/// performs any necessary cleaning.
		/// </summary>
		/// <param name="dataSet"></param>
		/// <param name="output"></param>
		/// <exception cref="InvalidOperationException">Thrown if there is a problem with the data.</exception>
		protected override void ValidateAndPrepareOutput(IDataSet dataSet, List<string> output)
		{
			//Verify that the expected number of lines were written.
			if (output.Count != dataSet.Instances.Count + 1)
			{
				throw new InvalidOperationException(
					string.Format("Expected {0} output lines, found {1}.", dataSet.Instances.Count, output.Count));
			}

			//Verify that the results begin with the expected output.
			if (!output[0].EndsWith("[,1]"))
			{
				throw new InvalidOperationException(
					string.Format("Output does not begin with expected header line, found '{0}'.", output[0]));
			}

			//Dump the header line, we don't need it.
			output.RemoveAt(0);
		}

		#endregion
	}
}